package leetcodejava.array;

import org.junit.Test;

/**
 * This is the solution of No. 1013 problem in the LeetCode,
 * the website of the problem is as follow:
 * https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum/
 * <p>
 * The description of problem is as follow:
 * ==========================================================================================================
 * 给你一个整数数组 A，只有可以将其划分为三个和相等的非空部分时才返回 true，否则返回 false。
 * <p>
 * 形式上，如果可以找出索引 i+1 < j 且满足 (A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1]) 就可以将数组三等分。
 * <p>
 * 示例 1：
 * 输出：[0,2,1,-6,6,-7,9,1,2,0,1]
 * 输出：true
 * 解释：0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
 * 示例 2：
 * 输入：[0,2,1,-6,6,7,9,-1,2,0,1]
 * 输出：false
 * 示例 3：
 * 输入：[3,3,6,5,-2,2,5,1,-9,4]
 * 输出：true
 * 解释：3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
 * 提示：
 * 3 <= A.length <= 50000
 * -10^4 <= A[i] <= 10^4
 * <p>
 * 来源：力扣（LeetCode）
 * * ==========================================================================================================
 *
 * @author zhangyu (zhangyuyu417@gmail.com)
 */
public class PartitionArrayIntoThreeParts1013 {
    @Test
    public void testPartitionArrayIntoThreeParts() {
        int[] A = {3, 3, 6, 5, -2, 2, 5, 1, -9, 4};
        boolean result = canThreePartsEqualSum2(A);
        System.out.println(result);
    }

    /**
     * 判断是否能把一个数组分成和相等的三部分
     *
     * @param A 数组
     * @return 布尔值
     */
    public boolean canThreePartsEqualSum(int[] A) {
        int count = 0;
        int sum = 0;
        for (int num : A) {
            sum += num;
        }
        if (sum % 3 != 0) {
            return false;
        }
        int partSum = 0;
        int partTotal = sum / 3;
        for (int num : A) {
            partSum += num;
            if (partSum == partTotal) {
                count++;
                partSum = 0;
            }
        }
        // 比如出现0，0，0，0，0情况
        return count >= 3;
    }

    /**
     * 判断是否能把一个数组分成和相等的三部分
     *
     * @param A 数组
     * @return 布尔值
     */
    public boolean canThreePartsEqualSum2(int[] A) {
        int sum = 0;
        for (int num : A) {
            sum += num;
        }
        if (sum % 3 != 0) {
            return false;
        }
        int start = 0, startSum = A[start];
        int end = A.length - 1, endSum = A[end];
        int average = sum / 3;
        while (start + 1 <= end) {
            if (startSum == average && endSum == average) {
                return true;
            }
            if (startSum != average) {
                startSum += A[++start];
            }
            if (endSum != average) {
                endSum += A[--end];
            }
        }
        return false;
    }
}
